#include "servermanager.h"

ServerManager::ServerManager()
{
    server = new QTcpServer();
    udpSocket = new QUdpSocket();
    udpSocket->bind(7777, QUdpSocket::ShareAddress);
    testMsg = "";

    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readUdp()));
    connect(server, SIGNAL(newConnection()), this, SLOT(newTcpConnection()));
}

void ServerManager::newTcpConnection() {
    SocketContainer *container = new SocketContainer();
    QTcpSocket *socket = server->nextPendingConnection();

    connect(socket, SIGNAL(readyRead()), this, SLOT(readTcp()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnect()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)));

    container->setSocket(socket);
    list.append(container);
}

void ServerManager::readUdp() {
    while (udpSocket->hasPendingDatagrams()) {
        QByteArray bytes;
        bytes.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(bytes.data(), bytes.size());

        QString msg = bytes.data();
        qDebug() << "UDP Message: " + msg;
    }
}

void ServerManager::readTcp() {
    for (SocketContainer* container : list) {
        QTcpSocket *socket = container->getSocket();

        if (socket->bytesAvailable() <= 0) continue;

        QDataStream in(socket);
        if (!container->isInfoSizeReady() && socket->bytesAvailable() >= (int)sizeof (qint16)) {
            qint16 infoSize;
            in >> infoSize;
            container->setInfoSize(infoSize);
            container->infoSizeReady();
        }

        if (container->isInfoSizeReady() && !container->isInfoReady() &&
            socket->bytesAvailable() >= container->getInfoSize()) {
            uint infoSize = container->getInfoSize();

            QByteArray bytes;
            bytes.resize(infoSize);
            in.readRawData(bytes.data(), bytes.size());
            container->setInfoHead(InfoHead::generateInfo(bytes));
            container->infoReady();
        }

        if (container->isInfoReady() && socket->bytesAvailable() >= container->getInfoHead()->getFileSize()) {
            OperationThread thread(container->getInfoHead(), &in);
            thread.run();
        }
    }
}

void ServerManager::disconnect() {
    int i = 0;
    for (SocketContainer* container : list) {
        QTcpSocket *socket = container->getSocket();
        if (socket->state() == QTcpSocket::UnconnectedState) {
            socket->deleteLater();
            list.removeAt(i);
        }
        i ++;
    }
}

void ServerManager::startServer() {
    QString host = "192.168.43.145";
    int port = 6666;
    server->listen(QHostAddress(host), port);
}

void ServerManager::error(QAbstractSocket::SocketError err) {
    qDebug() << err;
}
